home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games Extra 1996 September / Amiga Games Extra CD-ROM 9-1996.iso / userbox / publicdomain / vim-4.2 / src / alloc.c < prev    next >
C/C++ Source or Header  |  1996-06-09  |  7KB  |  382 lines

  1. /* vi:set ts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved        by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. /*
  10.  * alloc.c
  11.  *
  12.  * This file contains various routines dealing with allocation and
  13.  * deallocation of memory. And some funcions for copying text.
  14.  */
  15.  
  16. #include "vim.h"
  17. #include "globals.h"
  18. #include "proto.h"
  19.  
  20. /*
  21.  * Some memory is reserved for error messages and for being able to
  22.  * call mf_release_all(), which needs some memory for mf_trans_add().
  23.  */
  24. #define KEEP_ROOM 8192L
  25.  
  26. /*
  27.  * Note: if unsinged is 16 bits we can only allocate up to 64K with alloc().
  28.  * Use lalloc for larger blocks.
  29.  */
  30.     char_u *
  31. alloc(size)
  32.     unsigned        size;
  33. {
  34.     return (lalloc((long_u)size, TRUE));
  35. }
  36.  
  37. /*
  38.  * alloc() with check for maximum line length
  39.  */
  40.     char_u *
  41. alloc_check(size)
  42.     unsigned        size;
  43. {
  44. #if !defined(UNIX) && !defined(__EMX__)
  45.     if (sizeof(int) == 2 && size > 0x7fff)
  46.     {
  47.         EMSG("Line is becoming too long");
  48.         return NULL;
  49.     }
  50. #endif
  51.     return (lalloc((long_u)size, TRUE));
  52. }
  53.  
  54.     char_u *
  55. lalloc(size, message)
  56.     long_u            size;
  57.     int                message;
  58. {
  59.     register char_u   *p;            /* pointer to new storage space */
  60.     static int    releasing = FALSE;    /* don't do mf_release_all() recursive */
  61.     int            try_again;
  62.  
  63.     if (size <= 0)
  64.     {
  65.         EMSGN("Internal error: lalloc(%ld, )", size);
  66.         return NULL;
  67.     }
  68. #if defined(MSDOS) && !defined(DJGPP)
  69.     if (size >= 0xfff0)            /* in MSDOS we can't deal with >64K blocks */
  70.         p = NULL;
  71.     else
  72. #endif
  73.  
  74.     /*
  75.      * If out of memory, try to release some memfile blocks.
  76.      * If some blocks are released call malloc again.
  77.      */
  78.     for (;;)
  79.     {
  80.         if ((p = (char_u *)malloc(size)) != NULL)
  81.         {
  82.             if (mch_avail_mem(TRUE) < KEEP_ROOM && !releasing)
  83.             {                                 /* System is low... no go! */
  84.                     vim_free((char *)p);
  85.                     p = NULL;
  86.             }
  87.         }
  88.     /*
  89.      * Remember that mf_release_all() is being called to avoid an endless loop,
  90.      * because mf_release_all() may call alloc() recursively.
  91.      */
  92.         if (p != NULL || releasing)
  93.             break;
  94.         releasing = TRUE;
  95.         try_again = mf_release_all();
  96.         releasing = FALSE;
  97.         if (!try_again)
  98.             break;
  99.     }
  100.  
  101.     /*
  102.      * Avoid repeating the error message many times (they take 1 second each).
  103.      * Did_outofmem_msg is reset when a character is read.
  104.      */
  105.     if (message && p == NULL)
  106.         do_outofmem_msg();
  107.     return (p);
  108. }
  109.  
  110.     void
  111. do_outofmem_msg()
  112. {
  113.     if (!did_outofmem_msg)
  114.     {
  115.         emsg(e_outofmem);
  116.         did_outofmem_msg = TRUE;
  117.     }
  118. }
  119.  
  120. /*
  121.  * copy a string into newly allocated memory
  122.  */
  123.     char_u *
  124. strsave(string)
  125.     char_u           *string;
  126. {
  127.     char_u *p;
  128.  
  129.     p = alloc((unsigned) (STRLEN(string) + 1));
  130.     if (p != NULL)
  131.         STRCPY(p, string);
  132.     return p;
  133. }
  134.  
  135.     char_u *
  136. strnsave(string, len)
  137.     char_u        *string;
  138.     int         len;
  139. {
  140.     char_u *p;
  141.  
  142.     p = alloc((unsigned) (len + 1));
  143.     if (p != NULL)
  144.     {
  145.         STRNCPY(p, string, len);
  146.         p[len] = NUL;
  147.     }
  148.     return p;
  149. }
  150.  
  151. /*
  152.  * Same as strsave(), but any characters found in esc_chars are preceded by a
  153.  * backslash.
  154.  */
  155.     char_u *
  156. strsave_escaped(string, esc_chars)
  157.     char_u        *string;
  158.     char_u        *esc_chars;
  159. {
  160.     char_u        *p;
  161.     char_u        *p2;
  162.     char_u        *escaped_string;
  163.     unsigned    length;
  164.  
  165.     /*
  166.      * First count the number of backslashes required.
  167.      * Then allocate the memory and insert them.
  168.      */
  169.     length = 1;                            /* count the trailing '/' and NUL */
  170.     for (p = string; *p; p++)
  171.     {
  172.         if (vim_strchr(esc_chars, *p) != NULL)
  173.             ++length;                    /* count a backslash */
  174.         ++length;                        /* count an ordinary char */
  175.     }
  176.     escaped_string = alloc(length);
  177.     if (escaped_string != NULL)
  178.     {
  179.         p2 = escaped_string;
  180.         for (p = string; *p; p++)
  181.         {
  182.             if (vim_strchr(esc_chars, *p) != NULL)
  183.                 *p2++ = '\\';
  184.             *p2++ = *p;
  185.         }
  186.         *p2 = NUL;
  187.     }
  188.     return escaped_string;
  189. }
  190.  
  191. /*
  192.  * copy a number of spaces
  193.  */
  194.     void
  195. copy_spaces(ptr, count)
  196.     char_u    *ptr;
  197.     size_t    count;
  198. {
  199.     register size_t    i = count;
  200.     register char_u    *p = ptr;
  201.  
  202.     while (i--)
  203.         *p++ = ' ';
  204. }
  205.  
  206. /*
  207.  * delete spaces at the end of a string
  208.  */
  209.     void
  210. del_trailing_spaces(ptr)
  211.     char_u *ptr;
  212. {
  213.     char_u    *q;
  214.  
  215.     q = ptr + STRLEN(ptr);
  216.     while (--q > ptr && vim_iswhite(q[0]) && q[-1] != '\\' &&
  217.                                                            q[-1] != Ctrl('V'))
  218.         *q = NUL;
  219. }
  220.  
  221. /*
  222.  * Isolate one part of a string option where parts are separated with commas.
  223.  * The part is copied into buf[maxlen].
  224.  * "*option" is advanced to the next part.
  225.  * The length is returned.
  226.  */
  227.     int
  228. copy_option_part(option, buf, maxlen, sep_chars)
  229.     char_u        **option;
  230.     char_u        *buf;
  231.     int            maxlen;
  232.     char        *sep_chars;
  233. {
  234.     int        len = 0;
  235.     char_u    *p = *option;
  236.  
  237.     /* skip '.' at start of option part, for 'suffixes' */
  238.     if (*p == '.')
  239.         buf[len++] = *p++;
  240.     while (*p && vim_strchr((char_u *)sep_chars, *p) == NULL)
  241.     {
  242.         /*
  243.          * Skip backslash before a separator character and space.
  244.          */
  245.         if (p[0] == '\\' && vim_strchr((char_u *)sep_chars, p[1]) != NULL)
  246.             ++p;
  247.         if (len < maxlen - 1)
  248.             buf[len++] = *p;
  249.         ++p;
  250.     }
  251.     buf[len] = NUL;
  252.  
  253.     p = skip_to_option_part(p);    /* p points to next file name */
  254.  
  255.     *option = p;
  256.     return len;
  257. }
  258.  
  259. /*
  260.  * replacement for free() that ignores NULL pointers
  261.  */
  262.     void
  263. vim_free(x)
  264.     void *x;
  265. {
  266.     if (x != NULL)
  267.         free(x);
  268. }
  269.  
  270. #ifndef HAVE_MEMSET
  271.     void *
  272. vim_memset(ptr, c, size)
  273.     void    *ptr;
  274.     int        c;
  275.     size_t    size;
  276. {
  277.     register char *p = ptr;
  278.  
  279.     while (size-- > 0)
  280.         *p++ = c;
  281.     return ptr;
  282. }
  283. #endif
  284.  
  285. #ifdef VIM_MEMMOVE
  286. /*
  287.  * Version of memmove that handles overlapping source and destination.
  288.  * For systems that don't have a function that is guaranteed to do that (SYSV).
  289.  */
  290.     void
  291. vim_memmove(dst_arg, src_arg, len)
  292.     void    *src_arg, *dst_arg;
  293.     size_t    len;
  294. {
  295.     /*
  296.      * A void doesn't have a size, we use char pointers.
  297.      */
  298.     register char *dst = dst_arg, *src = src_arg;
  299.  
  300.                                         /* overlap, copy backwards */
  301.     if (dst > src && dst < src + len)
  302.     {
  303.         src +=len;
  304.         dst +=len;
  305.         while (len-- > 0)
  306.             *--dst = *--src;
  307.     }
  308.     else                                /* copy forwards */
  309.         while (len-- > 0)
  310.             *dst++ = *src++;
  311. }
  312. #endif
  313.  
  314. /*
  315.  * compare two strings, ignoring case
  316.  * return 0 for match, 1 for difference
  317.  */
  318.     int
  319. vim_strnicmp(s1, s2, len)
  320.     char_u    *s1;
  321.     char_u    *s2;
  322.     size_t    len;
  323. {
  324.     while (len)
  325.     {
  326.         if (TO_UPPER(*s1) != TO_UPPER(*s2))
  327.             return 1;                        /* this character different */
  328.         if (*s1 == NUL)
  329.             return 0;                        /* strings match until NUL */
  330.         ++s1;
  331.         ++s2;
  332.         --len;
  333.     }
  334.     return 0;                                /* strings match */
  335. }
  336.  
  337. /*
  338.  * Version of strchr() and strrchr() that handle unsigned char strings
  339.  * with characters above 128 correctly. Also it doesn't return a pointer to
  340.  * the NUL at the end of the string.
  341.  */
  342.     char_u    *
  343. vim_strchr(string, n)
  344.     char_u    *string;
  345.     int        n;
  346. {
  347.     while (*string)
  348.     {
  349.         if (*string == n)
  350.             return string;
  351.         ++string;
  352.     }
  353.     return NULL;
  354. }
  355.  
  356.     char_u    *
  357. vim_strrchr(string, n)
  358.     char_u    *string;
  359.     int        n;
  360. {
  361.     char_u    *retval = NULL;
  362.  
  363.     while (*string)
  364.     {
  365.         if (*string == n)
  366.             retval = string;
  367.         ++string;
  368.     }
  369.     return retval;
  370. }
  371.  
  372. /*
  373.  * Vim has its own isspace() function, because on some machines isspace()
  374.  * can't handle characters above 128.
  375.  */
  376.     int
  377. vim_isspace(x)
  378.     int        x;
  379. {
  380.     return ((x >= 9 && x <= 13) || x == ' ');
  381. }
  382.